package me.magicall.db.sql.select;

import java.util.Collection;

import me.magicall.db.sql.FollowingElements;
import me.magicall.db.sql.SqlElement;
import me.magicall.db.sql.condition.ConditionsOperator;
import me.magicall.db.sql.condition.OneCondition;
import me.magicall.db.sql.from.From;
import me.magicall.db.sql.from.Fromable;
import me.magicall.db.sql.where.Where;

/**
 * 整条select语句.
 * 
 * @author MaGiCalL
 */
public class Select extends FollowingElements<Selectedable> {
	From from;
	Where where;
	GroupBy groupBy;
	//having 暂缺
	OrderBy orderBy;

	public Select() {
		super();
	}

	public Select(final Selectedable firstElement) {
		super(firstElement);
	}

	@Override
	public StringBuilder appendTo(final StringBuilder sb) {
		//select
		sb.append(" ").append(getPrefix());
		final SqlElement firstColumn = getFirstElement();
		if (firstColumn == null) {
			sb.append(" * ");
		} else {
			firstColumn.appendTo(sb);
			for (final SqlElement otherColumn : getOtherElements()) {
				sb.append(",");
				otherColumn.appendTo(sb);
			}
			sb.append(" ");
		}
		//from
		if (from != null) {
			from.appendTo(sb);
		}
		if (where != null) {
			where.appendTo(sb);
		}
		//group by 
		if (groupBy != null) {
			groupBy.appendTo(sb);
		}
		//order by
		if (orderBy != null) {
			orderBy.appendTo(sb);
		}
		return sb;
	}

	public From getFrom() {
		if (from == null) {
			from = new From();
		}
		return from;
	}

	public void setFrom(final From from) {
		this.from = from;
	}

	public Where getWhere() {
		if (where == null) {
			where = new Where();
		}
		return where;
	}

	public void setWhere(final Where where) {
		this.where = where;
	}

	public GroupBy getGroupBy() {
		if (groupBy == null) {
			groupBy = new GroupBy();
		}
		return groupBy;
	}

	public void setGroupBy(final GroupBy groupBy) {
		this.groupBy = groupBy;
	}

	public OrderBy getOrderBy() {
		if (orderBy == null) {
			orderBy = new OrderBy();
		}
		return orderBy;
	}

	public void setOrderBy(final OrderBy orderBy) {
		this.orderBy = orderBy;
	}

	public void addFrom(final Collection<Fromable> elements) {
		getFrom().add(elements);
	}

	public void addFrom(final Fromable... elements) {
		getFrom().add(elements);
	}

	public void addFrom(final Fromable element) {
		getFrom().add(element);
	}

	public void addOrder(final OneOrder... elements) {
		getOrderBy().add(elements);
	}

	public void addOrder(final OneOrder element) {
		getOrderBy().add(element);
	}

	public void addOrder(final Collection<OneOrder> elements) {
		getOrderBy().add(elements);
	}

	public void addCondition(final Collection<OneCondition> elements) {
		getWhere().add(elements);
	}

	public void addCondition(final OneCondition... elements) {
		getWhere().add(elements);
	}

	public void addCondition(final OneCondition element) {
		getWhere().add(element);
	}

	public void addCondition(final OneCondition expression, final ConditionsOperator operator) {
		getWhere().addCondition(expression, operator);
	}

	public void addConditionUsingOr(final OneCondition expression) {
		getWhere().addConditionUsingOr(expression);
	}

	public void addGroupBy(final Collection<GroupByable> elements) {
		getGroupBy().add(elements);
	}

	public void addGroupBy(final GroupByable... elements) {
		getGroupBy().add(elements);
	}

	public void addGroupBy(final GroupByable element) {
		getGroupBy().add(element);
	}
}
